package mysql

import (
	"CampusCloudAid/models"
	"errors"
	"time"

	"gorm.io/gorm"
)

// FindMoneyByUid 查看用户的uid是否有效，如果有效则返回，用户钱包中的信息，如果无效，则返回，错误的无效 token
func FindMoneyByUid(uid int64) (money *models.AccountBalance, err error) {
	//根据用户id查找数据库中的金额信
	err = Conn.Where("user_id", uid).Find(&money).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, ErrInvalidId
		}
		return nil, err
	}
	return
}

// Recharge 充值金额
func Recharge(recharge *models.Recharge) (err error) {
	//将数据插入数据库
	err = Conn.Create(recharge).Error
	if err != nil {
		return err
	}
	return nil
}

// GiftCard 礼品卡兑换
func GiftCard(giftCard *models.GiftCard) (amount int, err error) {
	//查询数据库中礼品卡对应的金额
	g := new(models.GiftCard)
	err = Conn.Select("amount", "user_id").Where("card_id", giftCard.CardId).Find(&g).Error
	if err != nil {
		return 0, err
	}
	if g.UserId != 0 {
		return 0, ErrGiftCardUsed
	}
	//将用户id插入对应的礼品卡列中
	err = Conn.Model(&models.GiftCard{}).Where("card_id", giftCard.CardId).Update("user_id", giftCard.UserId).Error
	if err != nil {
		return 0, err
	}
	return g.Amount, nil
}

// UpdateMoney 将更新的礼品卡金额插入到用户账户中
func UpdateMoney(money *models.AccountBalance) (err error) {
	//将数据插入数据库
	err = Conn.Model(&models.AccountBalance{}).Where("user_id", money.UserId).Update("gift_card", money.GiftCard).Error
	if err != nil {
		return err
	}
	return nil
}

// 发布任务时消耗的金额：
func TaskPublishMoney(userId int64, taskId int64, taskAmount float64) error {
	// 查询用户钱包信息
	var balance models.AccountBalance
	if err := Conn.Where("user_id = ?", userId).First(&balance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("用户钱包信息不存在")
		}
		return err
	}

	// 判断余额是否足够支付任务金额
	if balance.WithDrawable < taskAmount {
		return errors.New("可转入余额不足")
	}

	// 扣除可转入余额
	balance.WithDrawable -= taskAmount

	// 更新用户钱包信息
	if err := Conn.Save(&balance).Error; err != nil {
		return err
	}

	// TODO: 在此处处理任务发布逻辑，例如保存任务信息等

	return nil
}

// TaskUnpublishMoney 任务从已发布变为已下架时钱包的变化： //传入用户id和该任务的钱，将任务中的钱返回到用户钱包中
func TaskUnpublishMoney(userId int64, taskId int64, taskAmount float64) error {
	// 查询用户钱包信息
	var balance models.AccountBalance
	if err := Conn.Where("user_id = ?", userId).First(&balance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("用户钱包信息不存在")
		}
		return err
	}

	// 更新可转入余额
	balance.WithDrawable += taskAmount

	// 更新用户钱包信息
	if err := Conn.Save(&balance).Error; err != nil {
		return err
	}

	// TODO: 在此处处理任务下架逻辑，例如更新任务状态等

	return nil
}

// 任务从已接收变成任务异常

// 任务异常时处理钱包变化
func TaskAbnormalMoney(receiverID, publishID int64, taskAmount float64, newStatus string) error {
	// 查询接收者钱包信息
	var receiverBalance models.AccountBalance
	if err := Conn.Where("user_id = ?", receiverID).First(&receiverBalance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("接收者钱包信息不存在")
		}
		return err
	}

	// 查询发布者钱包信息
	var publishBalance models.AccountBalance
	if err := Conn.Where("user_id = ?", publishID).First(&publishBalance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("发布者钱包信息不存在")
		}
		return err
	}

	// 更新接单人和发起者的钱包信息
	switch newStatus {
	case "1": // 发起人获胜，将钱传给发起人
		receiverBalance.Frozen -= taskAmount
		publishBalance.WithDrawable += taskAmount
	case "2": // 接收人获胜，将钱传给接收人
		receiverBalance.Frozen -= taskAmount
		receiverBalance.WithDrawable += taskAmount
	}

	// 保存更新后的钱包信息
	tx := Conn.Begin()
	if err := tx.Save(&receiverBalance).Error; err != nil {
		tx.Rollback()
		return err
	}
	if err := tx.Save(&publishBalance).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()

	return nil
}

//任务从已提交待确认变成任务异常
//同上,都是已异常进行操作

// 任务从已接收变成已提交待确认
// 从任务金额转入到待转入金额；
func ChangeTaskStatusToPendingConfirmation(taskID int64, userID int64, taskAmount float64) error {
	// 查询用户钱包信息
	var balance models.AccountBalance
	if err := Conn.Where("user_id = ?", userID).First(&balance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("用户钱包信息不存在")
		}
		return err
	}

	// 增加用户待转入金额
	balance.PendingTransfer += taskAmount

	// 更新用户钱包信息
	if err := Conn.Save(&balance).Error; err != nil {
		return err
	}

	// TODO: 在此处处理工单操作，如更新任务状态等

	return nil
}

// ChangeTaskStatusToCompleted 修改任务状态为已完成，并执行相应的逻辑
func ChangeTaskStatusToCompleted(taskID int64, receiverID int64, taskAmount float64) error {
	// 查询接单用户钱包信息
	var receiverBalance models.AccountBalance
	if err := Conn.Where("user_id = ?", receiverID).First(&receiverBalance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("接单用户钱包信息不存在")
		}

		return err
	}

	// 更新接单用户的待转入金额和可提现余额
	receiverBalance.PendingTransfer -= taskAmount
	receiverBalance.WithDrawable += taskAmount

	// 更新接单用户钱包信息
	if err := Conn.Save(&receiverBalance).Error; err != nil {
		return err
	}

	// 更新任务状态为已完成
	if err := Conn.Model(&models.Tasks{}).Where("id = ?", taskID).Update("task_status", "已完成").Error; err != nil {
		return err
	}
	task, _ := GetTask(taskID)
	// 4. 保存流水记录到数据库
	moneyFlow := models.MoneyFlow{
		FromUserID:  task.PublisherId, // 任务发起人id
		ToUserID:    task.ReceiverId,  // 任务接收者id
		Amount:      task.PaymentFee,  // 任务金额
		ArrivalTime: time.Now(),       // 当前时间
		Status:      "任务转账",           // 充值状态
		TaskID:      task.Id,          // 任务的ID
	}
	// TODO: 在此处处理工单操作，如更新任务状态等
	err := CreateFlow(moneyFlow)
	if err != nil {
		return err
	}
	return nil
}

// IncreaseFrozenMoney 方法增加接收者的冻结金额。
func IncreaseFrozenMoney(receiverID int64, taskAmount float64) error {
	// 查询接收者的余额信息
	var balance models.AccountBalance
	if err := Conn.Where("user_id = ?", receiverID).First(&balance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("未找到接收者的余额信息")
		}
		return err
	}

	// 增加冻结金额
	balance.Frozen += taskAmount

	// 更新接收者的余额信息
	if err := Conn.Save(&balance).Error; err != nil {
		return err
	}

	return nil
}

// UpdateReceiverBalance 方法通过从待转入金额中减去任务金额，并将其添加到可提现和冻结金额中，更新接收者的余额信息。
func UpdateReceiverBalance(receiverID int64, taskAmount float64) error {
	// 查询接收者的余额信息
	var balance models.AccountBalance
	if err := Conn.Where("user_id = ?", receiverID).First(&balance).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("未找到接收者的余额信息")
		}
		return err
	}

	// 从待转入金额中减去任务金额
	balance.PendingTransfer -= taskAmount

	// 将任务金额添加到可提现和冻结金额中
	//balance.WithDrawable -= taskAmount
	balance.Frozen += taskAmount

	// 更新接收者的余额信息
	if err := Conn.Save(&balance).Error; err != nil {
		return err
	}

	return nil
}
